perm filename FEATUR.PAL[SYS,HE] blob sn#122596 filedate 1975-02-07 generic text, type C, neo UTF8
COMMENT āŠ—   VALID 00009 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	.SBTTL	FEATURE EXTRACTOR
C00005 00003		
C00007 00004	
C00010 00005	
C00012 00006	
C00015 00007	
C00016 00008	 Scan window with gradient operator.
C00018 00009		MOV GRDDIR,A			 update counts
C00021 ENDMK
CāŠ—;
.SBTTL	FEATURE EXTRACTOR

;	this code does the initial processing for the
;	feature finder in MOVE

.INSRT VARIAN.PAL
.INSRT GRAD.PAL

; Input is a parameter block of the form:
PICID=0		;I.D. of the picture data block to process
WINW=2		;variance window width in samples
WINL=4		;window length in lines
VTOL=6		;threshold ≄ to accept variance (*10)
GTOL=10		;threshold ≄ to accept gradient magnitude
VDEB=12		;non-zero for variance debugging
GDEB=14		;non-zero for gradient debugging


; It returns an error number as follows:

;	-4	no free storage for feature output
;	-3	picture does not contain 4 bits samples
;	-2	did not find parameter block
;	-1	did not find picture block
;	0	finished - no data returned
;	1	returning complete feature data block
;	2	returning partial feature block - more to follow
;	3	returning variance debugging output
;	4	returning gradient debugging output

; Resending command will cause continue after #1-4

; Data returned is:
;	A. Variance debugging output : score, x, y
;	B. Gradient debugging output : magnitude, dx, dy, direction, x, y,
;		window X, window Y
;	C. Feature data block :
;		0	variance score
;		2	X coordinate of window [upper l.h. corner]
;		4	Y coordinate
;		6	number of gradient points to follow
;			-1 to reject previous partials
;		10	start of gradient data as in B above (1st 6 values)

OVERL=5		; is is the overlap between appli4cations of the window
	
; fixed data blocks

WINWRD:	0		; start of parameters to variance operator
WINSMP:	0
WINWID:	0
WINLEN:	0
BYTLEN:	0
WINSIZ:	0
WINSCR:	0		; start of variance debugging output
WINX:	0
WINY:	0

GRDWRD:	0		; start of parameters to gradient operator
GRDSMP:	0
GRDLEN:	0
GRDMAG:	0		; start of gradient debugging output
GRDDX:	0
GRDDY:	0
GRDDIR:	0
GRDX:	0
GRDY:	0
GWX:	0
GWY:	0

; pointers

PICTUR:	0		; picture data block
PARAM:	0		; parameter data block
RESBLK:	0		; result block start
SOBBLK:	0		; latest gradient block in result block
RESEND:	0		; end of result block

; limits for u.l. corner coords. during window scan

WLL:	0
WLR:	0
WLT:	0
WLB:	0

; gradient operator scan control

GXCNT:	0		; X counter
GYCNT:	0		; Y counter
GPTR:	0		; starting word of line
GBYT:	0		; starting sample of line
PRTFLG:	0		; non-zero if partial results sent
PNTCNT:	0		; # of gradient points
DIRCNT:			; direction counters
	.BLKB 8

; misc. variables 

XTMP:	0		; holds X counter during window scan
XCNT:	0		; holds initial value of X counter
YCNT:	0		; holds Y counter during window scan
VARSTR:	0		; holds starting word of scan
VARPTR:	0		; starting word of current line for window scan
VARINX:	0		; X increment in coords. for window scan
VARWDX:	0		; X increment in words		"
VARSMX:	0		; X increment in samples	"
VARINY:	0		; Y increment in coords.	"
VARWDY:	0		; Y increment in words		"
VARLCX:	0		; X offset in coords. for last window of line
VARLWX:	0		; X offset in words		"
VARLSX:	0		; X offset in samples		"
VARLCY:	0		; Y increment in coords. for last line of scan
VARLWY:	0		; Y increment in words		"

.MACRO	BREAK		; macro to divide offset into words and samples
	ASHC #-2,A
	ASL A
	SWAB B
	ASH #-6,B
	BIC #177774,B
.ENDM

COM6:	CLR OBUF+2
	MOV IBUF+2,-(SP)	; get parameter block
	JSR PC,SEARCH
	MOV (SP)+,NEW
	BNE LAB50
	MOV #-2,OBUF+4		;	error -2, not found
	JMP ERRRET
LAB50:	MOV PICID(NEW),-(SP)	; get picture block
	JSR PC,SEARCH
	MOV (SP)+,OLD
	BNE LAB51
	MOV #-1,OBUF+4		;	error -1, not found
	JMP ERRRET
LAB51:	CMP #4,BITS(OLD)
	BEQ LAB52
	MOV #-3,OBUF+4		;	error -3, not 4 bit samples
	JMP ERRRET
LAB52:	MOV ENDFRE,RESEND	; find end of free storage
	SUB #5, RESEND		; leave room for final block
	MOV RESEND,A
	SUB STRFRE,A
	CMP #11,A
	BLE LAB53
	MOV #-4,OBUF+4		; error -4, no space for output data
	JMP ERRRET

LAB53:	MOV STRFRE,RESBLK	; set up rest of pointers
	MOV OLD,PICTUR
	MOV NEW,PARAM
	MOV WINW(NEW),WINWID	; set up parameter blocks
	MOV WINL(NEW),WINLEN
	MOV WRDLIN(OLD),BYTLEN
	ASL BYTLEN		;	picture line length in bytes
	MOV WINW(NEW),B
	MUL WINL(NEW),B
	MOV B,WINSIZ		;	# of points in window
	MOV BYTLEN,GRDLEN
	MOV LEFT(OLD),WLL	; set up window scan limits
	INC WLL
	MOV TOP(OLD),WLT	;	all sides in at least 1 byte so
	INC WLT			;	gradient operator not outside pic
	MOV LEFT(OLD),WLR
	ADD NSAMP(OLD),WLR
	DEC WLR
	SUB WINW(NEW),WLR	;	right side and bottom are limits
	MOV TOP(OLD),WLB	;	of upper left corner of window
	ADD NLIN(OLD),WLB
	DEC WLB
	SUB WINL(NEW),WLB
	MOV OLD,VARPTR		; set up pointer to first word of scan line
	ADD PPNTR(OLD),VARPTR
	ADD BYTLEN,VARPTR
	MOV #1,WINSMP		; 	and first sample of scan line
	MOV WINWID,VARINX	; set up increments to control loop
	SUB #OVERL,VARINX
	MOV VARINX,A
	BREAK
	MOV A,VARWDX
	MOV B,VARSMX
	MOV WINLEN,VARINY
	SUB #OVERL,VARINY
	MOV VARINY,B
	MUL BYTLEN,B
	MOV B,VARWDY
	MOV WLR,B		; set up counts
	SUB WLL,B
	MOV VARINX,C
	JSR PC,CALC
	MOV A,XCNT
	MOV B,VARLCX
	MOV B,A
	BREAK
	MOV A,VARLWX
	MOV B,VARLSX
	MOV WLB,B
	SUB WLT,B

	MOV VARINY,C
	JSR PC,CALC
	MOV A,YCNT
	MUL BYTLEN,B
	MOV B,VARLWY
	MOV WLT,WINY		; now we are ready - init Y coordinate
	MOV #WINWRD,OLD		;	pointer for operator
	MOV VARPTR,VARSTR
VARLOP:	MOV VARPTR,WINWRD	;	init pointer
	MOV WLL,WINX		; Y loop - init X coordinate for line
	MOV XCNT,XTMP		;	init X counter for line
VARLI:	JSR PC,VARIAN		; X loop - call variance operator
	MOV PARAM,NEW
	TST VDEB(NEW)
	BEQ NOVD
	MOV #3,OBUF+4		;	send debug output if requested
	MOV #WINSCR,OBUF+2
	JSR PC,WAITL
NOVD:	CMP VTOL(NEW),WINSCR	;	test variance score
	BGT NOWIN		;	under threshold - continue
	JSR PC,SOBEL
	MOV PARAM,NEW
	MOV #WINWRD,OLD
NOWIN:	ADD VARINX,WINX		;	increment to next application
	ADD VARWDX,WINWRD
	ADD VARSMX,WINSMP
	CMP #4,WINSMP
	BGT NOINC
	SUB #4,WINSMP
	ADD #2,WINWRD
NOINC:	DEC XTMP
	BGT VARLI		;	and return to apply
	BLT LINEND		; end of line - test if done
	TST VARLCX
	BEQ LINEND
	MOV WLL,WINX		;	no - set up final application
	ADD VARLCX,WINX
	MOV VARPTR,WINWRD
	ADD VARLWX,WINWRD
	MOV VARLSX,WINSMP
	BR VARLI

LINEND:	ADD VARINY,WINY		; 	yes - increment to next line
	ADD VARWDY,VARPTR
	MOV #1,WINSMP
	DEC YCNT
	BGT VARLOP		;	and return to apply
	BLT VAREND		; end of scan - test if done
	TST VARLCY
	BEQ VAREND

	MOV WLT,WINY		;	no - set up final line
	ADD VARLCY,WINY
	MOV VARSTR,VARPTR
	ADD VARLWY,VARPTR
	BR VARLOP

VAREND:	CLR OBUF+4		; finished
	JMP ERRRET


; subr to finish setting up counts
; B is # of samples-1 in this direction
; C is increment
; returns count in A and last offset in B

CALC:	INC B			; number of samples
	MOV B,TEMP
	CLR A
	DIV C,A
	INC A			; count
	CMP #OVERL,B
	BLT LAB54
	CLR B			; not enough left over
	RTS PC			; no final application

LAB54:	MOV TEMP,B		; set up offset for final application
	RTS PC

TEMP:	0
; Scan window with gradient operator.
; At this point we are guaranteed that the window and the points
;just outside the perimeter are in image

SOBEL:	CLR PRTFLG		; set limits of scan
	CLR PNTCNT
	MOV WINLEN,GYCNT
	MOV WINWRD,GPTR
	SUB BYTLEN,GPTR
	MOV WINSMP,GBYT
	DEC GBYT
	BGE NODEC
	MOV #3,GBYT
	SUB #2,GPTR
NODEC:	MOV WINY,GRDY
	MOV RESBLK,NEW		; set up pointers
	MOV #GRDWRD,OLD
	MOV NEW,SOBBLK
	ADD #8,SOBBLK
	MOV WINSCR,(NEW)	; set up output header
	MOV WINX,2(NEW)
	MOV WINY,4(NEW)
	CLR 6(NEW)
	CLR DIRCNT		; clear direction count table
	CLR DIRCNT+2
	CLR DIRCNT+4
	CLR DIRCNT+6
GYSCN:	MOV WINWID,GXCNT	; set up one line of scan
	MOV GPTR,GRDWRD
	MOV GBYT,GRDSMP
	MOV WINX,GRDX
GXSCN:	JSR PC,GRAD		; apply operator
	MOV PARAM,NEW
	TST GDEB(NEW)
	BEQ NOGD		
	MOV #4,OBUF+4			; send debugging output
	MOV #GRDMAG,OBUF+2
	MOV WINX,GWX
	MOV WINY,GWY
	JSR PC,WAITL
NOGD:	CMP GTOL(NEW),GRDMAG		; test gradient magnitude
	BGT NOGRD			; under threshold
	MOV RESBLK,NEW			; over threshold
	INC 6(NEW)			; store results
	MOV SOBBLK,B
	MOV #GRDMAG,LENG
	MOV #6,A
GRDLOP:	MOV (LENG)+,(B)+
	SOB A,GRDLOP
	MOV B,SOBBLK
	MOV GRDDIR,A			; update counts
	INCB DIRCNT(A)
	INC PNTCNT
	CMP NEW,RESEND
	BLT NOGRD
	DEC PRTFLG			; out of space - return partial
	MOV RESBLK,OBUF+2		;	results
	ASR OBUF+2
	MOV #2,OBUF+4
	JSR PC,WAITL
	MOV NEW,SOBBLK			; and reset pointers
	ADD #8,SOBBLK
	CLR 6(NEW)
NOGRD:	INC GRDX			; update for next point
	INC GRDSMP
	CMP #4,GRDSMP
	BNE SAMBYT
	CLR GRDSMP
	ADD #2,GRDWRD
SAMBYT:	DEC GXCNT
	BGT GXSCN
	INC GRDY			; end of line - set up for next
	ADD BYTLEN,GPTR
	DEC GYCNT
	BGT GYSCN
	MOV #8,A			; end of scan - count peaks
	CLR B
	MOV #DIRCNT,LENG
PKLOOP:	MOVB (LENG)+,C
	BIC #177400,C
	CMP #2,C
	BGE NOPEAK
	INC B
NOPEAK:	SOB A,PKLOOP
	CMP #2,B
	BGT REJEC			; not enough peaks
	CMP #7,B
	BGT PKOK
	ASL PNTCNT
	CMP PNTCNT,WINSIZ
	BGT REJEC			; found texture
PKOK:	MOV RESBLK,OBUF+2		; we have a feature, return
	MOV #1,OBUF+4
	JSR PC,WAITL
SOBRET:	RTS PC

REJEC:	TST PRTFLG			; no peak - partial results sent?
	BEQ SOBRET
	MOV RESBLK,NEW			; yes - turn him off
	MOV #-1,6(NEW)
	BR PKOK